package cn.donting.web.desktop.sdk.web.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.http.HttpMethod;
import org.springframework.http.client.ClientHttpRequest;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.stereotype.Controller;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

/**
 * 404 转发到 对应开发地址
 *
 * @author donting
 * 2021-06-14 下午1:51
 */
@RestController
@RequestMapping("${server.error.path:${error.path:/error}}")

public class DevErrorController implements ErrorController {


    Logger logger = LoggerFactory.getLogger(DevErrorController.class);

    @Value("${webapp.dev.host}")
    String host;

    /**
     * 开发时代理转发
     *
     * @param request
     * @param httpServletResponse
     * @throws IOException
     */
    @RequestMapping
    public void error(HttpServletRequest request, HttpServletResponse httpServletResponse) throws IOException {
        try {
            if (httpServletResponse.getStatus() == 404) {
                String originUrl = request.getAttribute("request_origin_url").toString();
                logger.info("执行dev代理："+originUrl);
                URI newUri = new URI(host + originUrl);
                // 执行代理查询
                String methodName = request.getMethod();
                HttpMethod httpMethod = HttpMethod.resolve(methodName);
                if (httpMethod == null) {
                    return;
                }
                ClientHttpRequest delegate = new SimpleClientHttpRequestFactory().createRequest(newUri, httpMethod);
                Enumeration<String> headerNames = request.getHeaderNames();
                // 设置请求头
                while (headerNames.hasMoreElements()) {
                    String headerName = headerNames.nextElement();
                    Enumeration<String> v = request.getHeaders(headerName);
                    List<String> arr = new ArrayList<>();
                    while (v.hasMoreElements()) {
                        arr.add(v.nextElement());
                    }
                    delegate.getHeaders().addAll(headerName, arr);
                }
                StreamUtils.copy(request.getInputStream(), delegate.getBody());
                // 执行远程调用
                ClientHttpResponse clientHttpResponse = delegate.execute();
                httpServletResponse.setStatus(clientHttpResponse.getStatusCode().value());
                // 设置响应头
                clientHttpResponse.getHeaders().forEach((key, value) -> value.forEach(it -> {
                    httpServletResponse.setHeader(key, it);
                }));
                StreamUtils.copy(clientHttpResponse.getBody(), httpServletResponse.getOutputStream());

            }

        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            httpServletResponse.getOutputStream().write(e.getMessage().getBytes(StandardCharsets.UTF_8));
            return;
        }

    }
}
